(define-module (base-64)
  #:use-module (rnrs base)
  #:use-module ((guile)
                #:select (lambda* λ))
  ;; SRFI 69: hash tables
  #:use-module ((srfi srfi-69))
  #:export (chars
            char->integer
            integer->char))


(define chars
  #(#\A #\B #\C #\D #\E #\F #\G #\H
    #\I #\J #\K #\L #\M #\N #\O #\P
    #\Q #\R #\S #\T #\U #\V #\W #\X
    #\Y #\Z
    ;; 26
    #\a #\b #\c #\d #\e #\f #\g #\h
    #\i #\j #\k #\l #\m #\n #\o #\p
    #\q #\r #\s #\t #\u #\v #\w #\x
    #\y #\z
    ;; 52
    #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9
    ;; 62
    #\+ #\/
    ;; 64
    ))


(define translation-table
  (alist->hash-table
   '((#\A .  0) (#\B .  1) (#\C .  2) (#\D .  3) (#\E .  4) (#\F .  5) (#\G .  6) (#\H .  7)
     (#\I .  8) (#\J .  9) (#\K . 10) (#\L . 11) (#\M . 12) (#\N . 13) (#\O . 14) (#\P . 15)
     (#\Q . 16) (#\R . 17) (#\S . 18) (#\T . 19) (#\U . 20) (#\V . 21) (#\W . 22) (#\X . 23)
     (#\Y . 24) (#\Z . 25)
     ;; 26
     (#\a . 26) (#\b . 27) (#\c . 28) (#\d . 29) (#\e . 30) (#\f . 31) (#\g . 32) (#\h . 33)
     (#\i . 34) (#\j . 35) (#\k . 36) (#\l . 37) (#\m . 38) (#\n . 39) (#\o . 40) (#\p . 41)
     (#\q . 42) (#\r . 43) (#\s . 44) (#\t . 45) (#\u . 46) (#\v . 47) (#\w . 48) (#\x . 49)
     (#\y . 50) (#\z . 51)
     ;; 52
     (#\0 . 52) (#\1 . 53) (#\2 . 54) (#\3 . 55) (#\4 . 56) (#\5 . 57) (#\6 . 58) (#\7 . 59)
     (#\8 . 60) (#\9 . 61)
     ;; 62
     (#\+ . 62) (#\/ . 63))))


(define char->integer
  (λ (char)
    (hash-table-ref translation-table char)))


(define integer->char
  (λ (int)
    (vector-ref chars int)))
